在說明如何使用OVN之前,想像一下,在建立邏輯網路後,一定要有虛擬機器來驗證網路是否連通,如果安裝真正的虛擬機器來測試,未免也太花時間了。在我們的介紹OVN的過程中,我們會透過veth虛擬網絡設備,您可以簡單地模擬虛擬機器的網絡卡,而不需要安裝實際的虛擬機器。veth是一種虛擬網絡設備,由Linux內核支援。它包含兩端,且這兩端一定是成對出現。veth的兩端可以在不同的網路namespace中,這使得不同的虛擬網絡之間可以相互通信。當一端收到封包時,封包會被轉發到另一端,這使得通信可以在虛擬網絡之間進行。veth的特性使得它在虛擬化技術中非常有用。虛擬機器或容器中看到的網路卡,實際上都是透過veth這個虛擬裝置來實現的。使用veth可以方便地模擬虛擬機器的網絡連通性。
延續昨天完成的測試環境,我們將在controller上建立二個veth pair以及一個Linux Bridge,一旦分別將二個veth pair的一端接到Bridge後,二個namespace就可以
透過br0進行溝通。先來看完成後的長像吧~。
在實驗的過程中,因為有些指令比較煩鎖,所以已經先整理成bash的函數,先讓大家有個大致上的理解,可以幫助大家更容易聚焦在指令的目的,趕快來試試吧。相關建立namespace指令已經整理在helper.sh
裡,所以先source這個script後來試看看吧。
sudo su
git clone https://github.com/ogre0403/iTHome-2023.git
cd /opt/iTHome-2023/day-02
source helper.sh
# 建立namespace ns1, 並給定IP
create-ns ns1 192.168.1.1
# 檢查ns1 namespace的IP
ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether e6:63:b5:c1:4f:f4 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.1/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::e463:b5ff:fec1:4ff4/64 scope link
valid_lft forever preferred_lft forever
# 建立namespace ns2, 並給定IP
create-ns ns2 192.168.1.2
# 檢查ns2 namespace的IP
ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether aa:cd:c8:b5:7c:8f brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a8cd:c8ff:feb5:7c8f/64 scope link
valid_lft forever preferred_lft forever
上面建立veth pair的 create-ns function, 請參考helper.sh囉。關於veth 的原理,則可以參考Day 24: 什麼是 veth pair?
。
我們建立了二組veth pair後, 並將二組的其中一端分別放進ns1 與ns2,所以在default namespace,仍可以看到二組pair的另一端。
ip link show type veth
8: veth-ns1-br@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
link/ether ea:91:39:fd:8e:8c brd ff:ff:ff:ff:ff:ff link-netns ns1
10: veth-ns2-br@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
link/ether 72:6c:36:50:c9:11 brd ff:ff:ff:ff:ff:ff link-netns ns2
至於在default namespace的二個veth pair的另一端,我們要將其放至Linux Bridge上,所以,先建立一個Linux Bridge, 叫做br0吧。剛建好的br0,可以看到在並沒有任何的interface在br0上。
create-br br0
brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.726c3650c911 no
所以再來要把在default namespace的二個veth pair放至br0。放進去後,就可以看到br0上有二個interface。
assign-iface-to-br br0
brctl show
bridge name bridge id STP enabled interfaces
br0 8000.0eea0d2b6c4a no veth-ns1-br
veth-ns2-br
一旦veth pair放至br0後,我們就可以檢查二個namesapce是否能連互相連通。在這裡我們是進入到ns1這個namespace對另一個namespace的IP執行Ping.
ip netns exec ns1 ping -c 4 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.037 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.047 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.037 ms
--- 192.168.1.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3055ms
rtt min/avg/max/mdev = 0.037/0.044/0.058/0.008 ms
剛才先幫大家複習如何用Linux Bridge連接二個veth。若要改用OVN的logical switch連接veth, 作法也非常類似,下圖就是我們要完成的目標。可以看到在default namespace的二個veth pair,不是放在Linux Bridge上,而是放在br-int這個OVN幫我們建立的bridge上。接下來來試看看吧。
建立veth pair和Linux Bridge的時候完全相同,但我們這邊不重新建立二組新的veth pair, 建立新的veth pair讓大家自己練習。我們這裡的作法,是直接把前一個實驗建立好的Linux Bridge br0直接刪掉,等一下再將這二組veth pair接到OVN的logical switch上。想當然爾,一旦沒有br0,二個namespace就沒辦法傳送封包,這就是為什麼這一步ping會不通的原因。
teardown-br br0
ip netns exec ns1 ping -c 4 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
^C
--- 192.168.1.2 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1019ms
在Linux Bridge的實驗裡,不論是在controller或是hypervisor,都能夠建立br0。但在OVN的實驗裡,一定要在controller上執行。因為會使用ovn-nbctl建立邏輯網路,這一步一定要在controller上執行,讓ovn-nbctl才能夠和North bound DB溝通。
建立後,透過ovn-nbctl可以看到有一個logical switch ls0
被建立出來,而且,現在logical switch上有二個interface。
# 建立名為 ls0的logical switch,並在上面加上logical switch port
create-ovn-ls-and-lsp ls0
ovn-nbctl show
switch e35b11c6-4af8-42f7-9d8c-f2d35ad30afd (ls0)
port ls0-ns2
addresses: ["d6:ba:2e:b8:65:da"]
port ls0-ns1
addresses: ["e6:3c:39:39:3d:f4"]
還記得曾經提過的ovn-sbctl這個指令,可以查詢邏輯網路和實體網路的綁定關係嗎? 先來看一下目前的綁定關係。但是現在只顯示目前有二個chassis,分別是我們的controller與hypervisor二個節點,沒有其他重要的資訊。這是因為,我們現在還沒有把進行實體和邏輯綁定的操作,我們繼續往下。
ovn-sbctl show
Chassis "1cea777a-68eb-4396-a5c2-6f3c875eb604"
hostname: controller
Encap geneve
ip: "192.168.33.10"
options: {csum="true"}
Chassis "a17b40ba-4668-40fc-9739-c9e72f0e2cab"
hostname: hypervisor
Encap geneve
ip: "192.168.33.20"
options: {csum="true"}
和Linux Bridge的實驗很類似,再來要把veth pair的另一端接到logcial switch上,詳細的指令我們稍等再介紹,先來看一下完成後的交換器的長像如何。這裡有幾點要特別注意:
同時,我們可以用ovs-vsctl檢查controller上,目前br-int上,多了二個interface, 分別是veth-ns1-br
& veth-ns2-br
. 到此,我們已經把default namespace的二個veth pair放至logical switch上。
# 將所有namespace的另一端接到ls0
assign-iface-to-ovn-lsp ls0
ovs-vsctl show
20264d18-f841-4ad9-a5ad-5c7e39b1524a
Bridge br-int
fail_mode: secure
Port veth-ns1-br
Interface veth-ns1-br
Port ovn-ee4404-0
Interface ovn-ee4404-0
type: geneve
options: {csum="true", key=flow, remote_ip="192.168.33.20"}
Port br-int
Interface br-int
type: internal
Port veth-ns2-br
Interface veth-ns2-br
ovs_version: "2.13.8"
我們再試一次ovn-sbctl,現在可以看到在controller的chassis上,有二個Port綁定到logical switch上的ls0-ns1與ls0-ns2這二個interface.
ovn-sbctl show
Chassis "1cea777a-68eb-4396-a5c2-6f3c875eb604"
hostname: controller
Encap geneve
ip: "192.168.33.10"
options: {csum="true"}
Port_Binding ls0-ns2
Port_Binding ls0-ns1
Chassis "a17b40ba-4668-40fc-9739-c9e72f0e2cab"
hostname: hypervisor
Encap geneve
ip: "192.168.33.20"
options: {csum="true"}
一旦veth pair放至logical switch後,我們就可以檢查二個namespace是否能連互相連通。在這裡我們是進入到ns1這個namespace對另一個namespace的IP執行Ping.
ip netns exec ns1 ping -c 4 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.053 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.046 ms
--- 192.168.1.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3051ms
rtt min/avg/max/mdev = 0.046/0.052/0.066/0.008 ms
最後,可以用下面的指令,將logical switch與namespace刪除。
teardown-ovn-ls ls0
teardown-ns ns1 ns2
我們今天延續昨天完成的測試環境,用veth pair 模擬虛擬機器的網路卡,再測試環境上面分別建立了Linux Bridge 與 OVN logical switch, 將二組veth pair 相連。最重要的是,透過ovn-nbctl,我們建立了一個最簡單的logical switch,並驗證二組veth pair是能透過logical switch連通。到目前,對於OVN的基本運作,應該有進一步的體會了吧。是不是很有趣呢~